using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using XmlObjects.XmlObjectHydrator;
using XmlObjects.XmlObjectHydrator.Parsers;

namespace XmlObjects.XmlDocumentMarkup
{

	public class XmlObjectHydrator<T> : IHydrator, IXmlParser<T>
	{
		private static Dictionary<Type, IXmlParser> readerDictionary;

		static readonly Type iListType = Type.GetType("System.Collections.Generic.List`1");


		static XmlObjectHydrator()
		{
//			readerDictionary = new Dictionary<Type, IXmlParser>();
//			readerDictionary.Add(typeof(string), new StringElementReader() );
//			readerDictionary.Add(typeof(int), new ParseableReader<int>() );
//			readerDictionary.Add(typeof(float), new ParseableReader<float>() );
//			readerDictionary.Add(typeof(double), new ParseableReader<double>() );
//			readerDictionary.Add(typeof(decimal), new ParseableReader<decimal>() );
//			readerDictionary.Add(typeof(long), new ParseableReader<long>() );
//			readerDictionary.Add(typeof(DateTime), new ParseableReader<DateTime>() );
//
//			readerDictionary.Add(typeof(FileInfo), new InstantiableReader<FileInfo>() );
//			readerDictionary.Add(typeof(DirectoryInfo), new InstantiableReader<DirectoryInfo>() );

			int? foo = null;
			int foo2 = 3;
			

		}

		public static void Hydrate(object anObject, XmlNode anXmlNode)
		{
			/// Try to get a hydrator for this object's type. if one doesn't exist, create one.
			///  
			
		}

		private Type theType;

		List<IHydrator> hydrators = new List<IHydrator>();

		public XmlObjectHydrator(Type theType)
		{
			this.theType = theType;
			foreach (PropertyInfo propertyInfo in theType.GetProperties())
			{
				if (Attribute.IsDefined(propertyInfo, typeof(PropertyAttribute)))
				{
					//  Is it an attribute?  An element?  An Array?  An IList?
					Type propertyType = propertyInfo.PropertyType;
					if (propertyType.IsGenericType)
					{
						Type theGenericType = propertyType.GetGenericTypeDefinition();
						if (theGenericType == iListType)
						{
							throw new Exception("TODO: Finish handling IList properties.");
						}
					}
					else if (propertyType.IsArray)
					{
						Type theArrayType = propertyType.GetElementType();
					}


					
				}
			}
		}

		public void ReadXml(object obj, XmlNode node)
		{
			foreach (IHydrator hydrator in hydrators)
				hydrator.ReadXml(obj, node);
		}

		public void WriteXml(object obj, XmlNode node)
		{
			foreach (IHydrator hydrator in hydrators)
				hydrator.WriteXml(obj, node);
		}

		public T GetValue(XmlNode node)
		{
			throw new NotImplementedException();
		}
	}

	internal interface IHydrator
	{
		void ReadXml(object obj, XmlNode node);
		void WriteXml(object obj, XmlNode node);
	}

	class IListHydrator<T> : IHydrator
	{
		
		private string select = "foo";
		private PropertyInfo propertyInfo = null;
		private PropertyAttribute propertyAttribute;
		private IXmlParser<T> parser = null;

		public IListHydrator(PropertyInfo propertyInfo)
		{
			propertyAttribute = (PropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyAttribute));
		}

		public void ReadXml(object obj, XmlNode node)
		{
			List<T> theList = new List<T>();
			XmlNodeList nodeList = node.SelectNodes(select);
			foreach (XmlNode xmlNode in nodeList)
			{
				theList.Add(parser.GetValue(xmlNode));
			}
			propertyInfo.SetValue(obj, theList, null);
		}

		public void WriteXml(object obj, XmlNode node)
		{
			throw new NotImplementedException();
		}
	}
}